import abc
from abc import ABC

from sqlalchemy import text

from aop.aop_auto_commit import auto_commit_rollback
from db.mysql_pool import MySQLPool
from utils.str_utils import determine_crud_type


class BaseService(ABC):
    def __init__(self):
        self.mysql_pool = MySQLPool(self.db_config())
        self.session = self.mysql_pool.get_session()

    @abc.abstractmethod
    def db_config(self) -> dict[str, str]:
        raise NotImplementedError

    def get_session(self):
        return self.mysql_pool.get_session()

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('__exit__', self.__class__.__name__)
        self.session.close()  # 只关闭 session，不关闭连接池

    def close_pool(self):
        self.mysql_pool.close()

    def close_session(self):
        self.session.close()

    def execute_native_sql(self, sql_query):
        """执行原生SQL查询.

        Args:
            session: SQLAlchemy会话对象.
            sql_query: 要执行的SQL查询字符串.

        Returns:
            list: 查询结果列表，每个元素代表一行数据。
        """
        if sql_query is None:
            raise ValueError('sql_query cannot be None')
        sql = text(sql_query)
        t = determine_crud_type(sql_query)
        if t == 'R':
            result = self.session.execute(sql)
            return result.rowcount
        elif t == 'U':
            return self.update(sql)
        else:
            raise ValueError('不支持此操作')

    @auto_commit_rollback
    def update(self, sql):
        result = self.session.execute(sql)
        # print(self.db_config())
        return result.rowcount
